/*!
 * controller/utils.js
 * © 2009 BlooDHounD
 * @author BlooDHounD <http://www.controller.by>
 */

if ( !window.controller ) throw new Error( '"controller" not initialized' );

if ( !controller.utils ) {

	/**
	 * @package
	 * @final
	 * @namespace	controller
	 * @author		BlooDHounD	<http://www.controller.by>
	 */
	controller.utils = new ( function() {

		//--------------------------------------------------------------------------
		//
		//  Class variables
		//
		//--------------------------------------------------------------------------

		var	msie =	controller.browser.getMSIE();

		//--------------------------------------------------------------------------
		//
		//  Constructor
		//
		//--------------------------------------------------------------------------

		/**
		 * @private
		 * @constructor
		 */
		var Utils = new Function(),
			UtilsPrototype = Utils.prototype;

		//--------------------------------------------------------------------------
		//
		//  Methods
		//
		//--------------------------------------------------------------------------

		/**
		 * @method
		 * @param	{Object}	scope
		 * @param	{Function}	func
		 * @return	{Function}
		 */
		UtilsPrototype.createDelegate = function(scope, func) {
			return function() {
				func.apply( scope, arguments );
			};
		};

		/**
		 * @method
		 * @param	{Object}	scope
		 * @param	{Function}	func
		 * @return	{Function}
		 */
		UtilsPrototype.createDeferredDelegate = function(scope, func, onError) {
			if ( msie ) {
				return function() {
					var a = arguments;
					setTimeout(
						( onError
							?	function() {
									try {
										func.apply( scope, a );
									} catch ( e ) {
										onError.call( scope, e );
									}
								}
							:	function() {
									func.apply( scope, a );
								}
						),
						1
					);
				};
			} else {
				var delegate = ( onError
					?	function(args) {
							try {
								func.apply( scope, args );
							} catch ( e ) {
								onError.call( scope, e );
							}
						}
					:	function(args) {
							func.apply( scope, args );
						}
				);
				return function() {
					setTimeout( delegate, 1, arguments );
				};
			}
		};

		/**
		 * @method
		 * @param	{Object}	scope
		 * @param	{Function}	func
		 */
		UtilsPrototype.deferredCall = function(scope, func) {
			var	args =	Array.prototype.slice.call( arguments, 2 );
			if ( args.length <= 0 && !scope ) {
				setTimeout( func, 1 );
			} else if ( msie ) {
				setTimeout(
					function() {
						func.apply( scope, args );
					},
					1
				);
			} else {
				args.unshift(
					( scope ? this.createDelegate( scope, func ) : func ),
					1
				);
				setTimeout.apply( window, args );
			}
		};

		/**
		 * @method
		 * @return	{Number}
		 */
		UtilsPrototype.getTime = function() {
			return ( new Date() ).getTime();
		};

		/**
		 * @method
		 * @param	{String}	value
		 * @return	{String}
		 */
		UtilsPrototype.encodeHTML = function(value) {
			var	result =	'',
				l =			value.length,
				i,
				j =			0,
				r;
			for ( i=0; i<l; i++ ) {
				switch ( value.charAt( i ) ) {
					case '&':	r = '&amp;';	break;
					case '<':	r = '&lt;';		break;
					case '>':	r = '&gt;';		break;
					case '"':	r = '&quot;';	break;
					//case '\'':	r = '&#39;';	break;
				}
				if ( r ) {
					if ( j != i ) result += value.substring( j, i );
					result += r;
					j = i + 1;
					r = null;
				}
			}
			result += value.substr( j );
			return result;
		};

		/**
		 * @method
		 * @param	{String}	value
		 * @return	{String}
		 */
		UtilsPrototype.decodeHTML = function(value) {
			var result =	'',
				l =			value.length,
				i,
				j =			0,
				c,
				r;
			for ( i=0; i<l; i++ ) {
				switch ( value.charAt( i ) ) {
					case '&':
						switch ( value.charAt( i + 1 ) ) {
							case 'q': if ( value.substr( i + 2, 4 ) == 'uot;' ){ r = '"'; c = 6; } break;
							case 'g': if ( value.substr( i + 2, 2 ) == 't;' )	{ r = '>'; c = 4; } break;
							case 'l': if ( value.substr( i + 2, 2 ) == 't;' )	{ r = '<'; c = 4; } break;
							case 'a': if ( value.substr( i + 2, 3 ) == 'mp;' )	{ r = '&'; c = 5; } break;
						}
						break;

				}
				if ( r ) {
					if ( j != i ) result += value.substring( j, i );
					result += r;
					j = i + c;
					r = null;
				}
			}
			result += value.substr( j );
			return result;
		};

		/**
		 * @method
		 * @param	{Array}		arr
		 * @param	{Object}	o
		 * @return	{Number}
		 */
		UtilsPrototype.indexOf = ( msie
			?	function(arr, o) {
					var l = arr.length,
						i;
					for ( i=0; i<l; i++ ) {
						if ( arr[ i ] === o ) return i;
					}
					return -1;
				}
			:	function(arr, o) {
					return arr.indexOf( o );
				}
		);

		/**
		 * @method
		 * @param	{Array}		arr
		 * @param	{Object}	o
		 * @return	{Number}
		 */
		UtilsPrototype.lastIndexOf = ( msie
			?	function(arr, o) {
					var i = arr.length - 1;
					for ( i; i>=0; i-- ) {
						if ( arr[ i ] === o ) return i;
					}
					return -1;
				}
			:	function(arr, o) {
					return arr.indexOf( o );
				}
		);
		UtilsPrototype.dateFormat = function(timestamp, format) {
			format = typeof(format) == 'undefined' ? 'datetime' : format;

			var date = new Date(timestamp*1000);

			var d = date.getDate().toString();
			var m = (date.getMonth() + 1).toString();
			var y = date.getFullYear().toString();

			var h = date.getHours().toString();
			var i = date.getMinutes().toString();
			var s = date.getSeconds().toString();

			if (i < 10) i = "0"+i;
			if (s < 10) s = "0"+s;
			if (d < 10) d = "0"+d;
			if (m < 10) m = "0"+m;

			var result = '';
			switch (format) {
				default:
				case 'datetime':
					result = d+"."+m+"."+y+" "+h+":"+i+":"+s;
					break;
				case 'time':
					result = h+":"+i+":"+s;
					break;
				case 'date':
					result = m+"/"+d+"/"+y.substring(2);
					break;
				case 'raw':
					result = {
						day: d,
						month: m,
						year: y,
						hours: h,
						minutes: i,
						seconds: s
					};
					break;
			}

			return result;
		}

		UtilsPrototype.durationFormat = function(secondsLast, type) {
			var days    = Math.floor(secondsLast / 86400).toString();
			var hours   = Math.floor(secondsLast % 86400 / 3600).toString();
			var minutes = Math.floor(secondsLast % 3600 / 60).toString();
			var seconds = Math.floor(secondsLast % 60).toString();

			type = type || 0;
			if (type == 0) {

				while (hours.length < 2) {
					hours = '0' + hours;
				}
				
				while (minutes.length < 2) {
					minutes = '0' + minutes;
				}

				while (seconds.length < 2) {
					seconds = '0' + seconds;
				}
				
				return hours + ':' + minutes + ':' + seconds; 
			} else if (type == 1) {
				var ret = '';
				if (parseInt(days) > 0) ret = days.toString()+'дн.';
				if (parseInt(hours) > 0) ret += hours.toString()+'час.';
				
				if (parseInt(minutes)) {
					if (seconds >= 30) minutes++;
					ret += (hours?' ':'') + minutes.toString() + 'мин.';
				}
				
				if (!parseInt(hours) && !parseInt(minutes) && parseInt(seconds)) ret = seconds.toString() + 'сек';
				return ret;
			} else {
				return '0:00:00';
			}
		}
		/**
		 * @method
		 * @override
		 * @return	{String}
		 */
		UtilsPrototype.toString = function() {
			return '[package utils]';
		};

		return Utils;

	}() );

}
